import os
import time
from kubernetes import client, config
from nacos import NacosClient
from typing import Dict, List, Set


class MultiNamespacePodMonitor:
    def __init__(self):
        # 初始化客户端
        self.init_kubernetes_client()

        # 配置加载
        self.namespaces = self.parse_namespaces_config()
        self.nacos_client = NacosClient(
            server_addresses=os.getenv("NACOS_SERVERS", "nacos:8848"),
            namespace=os.getenv("NACOS_NAMESPACE", "public"),
            username=os.getenv("NACOS_USER", "nacos"),
            password=os.getenv("NACOS_PASS", "nacos")
        )

        # 监控参数
        self.check_interval = int(os.getenv("CHECK_INTERVAL", "30"))
        self.abnormal_threshold = int(os.getenv("ABNORMAL_THRESHOLD", "5")) * 60  # 转为秒

        # 异常状态跟踪 {namespace: {pod_name: abnormal_data}}
        self.abnormal_pods: Dict[str, Dict[str, Dict]] = {}

        # 企微配置
        self.wecom_webhook = os.getenv("WECOM_WEBHOOK")

    def parse_namespaces_config(self) -> Set[str]:
        """解析Namespace配置，支持多种格式"""
        # 方式1：环境变量（逗号分隔）
        if "WATCH_NAMESPACES" in os.environ:
            return set(ns.strip() for ns in os.getenv("WATCH_NAMESPACES").split(",") if ns.strip())

        # 方式2：配置文件（可选实现）
        # 这里可以添加从configmap/secret读取的逻辑


        # 默认值
        return {"default"}

    def init_kubernetes_client(self):
        try:
            config.load_incluster_config()
        except:
            config.load_kube_config()
        self.k8s_api = client.CoreV1Api()

    def check_all_namespaces(self):
        """检查所有配置的namespace"""
        for ns in self.namespaces:
            try:
                self.check_namespace_pods(ns)
            except Exception as e:
                print(f"Error checking namespace {ns}: {str(e)}")

    def check_namespace_pods(self, namespace: str):
        """检查单个namespace下的pod状态"""
        pods = self.k8s_api.list_namespaced_pod(namespace=namespace)
        current_time = time.time()

        # 初始化namespace记录
        if namespace not in self.abnormal_pods:
            self.abnormal_pods[namespace] = {}

        active_pods = set()

        for pod in pods.items:
            pod_name = pod.metadata.name
            active_pods.add(pod_name)

            # 状态检查
            is_abnormal = (
                    pod.status.phase != "Running" or
                    not all(
                        condition.status == "True"
                        for condition in pod.status.conditions
                        if condition.type == "Ready"
                    )
            )

            if is_abnormal:
                self.handle_abnormal_pod(namespace, pod_name, current_time)
            else:
                self.handle_normal_pod(namespace, pod_name)

        # 清理已不存在的pod记录
        self.cleanup_removed_pods(namespace, active_pods)

    def handle_abnormal_pod(self, namespace: str, pod_name: str, current_time: float):
        """处理异常pod"""
        if pod_name not in self.abnormal_pods[namespace]:
            self.abnormal_pods[namespace][pod_name] = {
                "start_time": current_time,
                "reported": False
            }
        else:
            record = self.abnormal_pods[namespace][pod_name]
            if not record["reported"] and (current_time - record["start_time"]) >= self.abnormal_threshold:
                if self.check_nacos_registration(pod_name):
                    self.send_wecom_alert(namespace, pod_name)
                    self.abnormal_pods[namespace][pod_name]["reported"] = True

    def handle_normal_pod(self, namespace: str, pod_name: str):
        """处理恢复正常的pod"""
        if pod_name in self.abnormal_pods[namespace]:
            del self.abnormal_pods[namespace][pod_name]
            print(f"Pod {pod_name} in namespace {namespace} returned to normal")

    def cleanup_removed_pods(self, namespace: str, active_pods: Set[str]):
        """清理已删除的pod记录"""
        for pod_name in list(self.abnormal_pods[namespace].keys()):
            if pod_name not in active_pods:
                del self.abnormal_pods[namespace][pod_name]

    def check_nacos_registration(self, service_name: str) -> bool:
        """检查Nacos中服务注册状态"""
        try:
            instances = self.nacos_client.list_naming_instance(
                service_name=service_name,
                group_name="DEFAULT_GROUP"
            )
            # 检查是否有健康实例
            if instances and any(instance["healthy"] for instance in instances["hosts"]):
                return True
            return False
        except Exception as e:
            print(f"Error checking nacos registration: {str(e)}")
            return False
    def send_wecom_alert(self, namespace: str, pod_name: str):
        """发送带namespace信息的告警"""
        message = {
            "msgtype": "markdown",
            "markdown": {
                "content": f"**K8s跨Namespace监控告警**\n"
                           f"> 命名空间: `{namespace}`\n"
                           f"> Pod名称: `{pod_name}`\n"
                           f"> 异常持续时间: `{self.abnormal_threshold // 60}分钟`\n"
                           f"> 当前状态: Pod异常但Nacos注册状态仍正常\n\n"
                           f"**建议操作**:\n"
                           f"1. 检查Pod日志: `kubectl logs -n {namespace} {pod_name}`\n"
                           f"2. 检查Pod描述: `kubectl describe pod -n {namespace} {pod_name}`"
            }
        }
        # ... 保持原有发送逻辑 ...

    def start_monitoring(self):
        """启动监控循环"""
        print(f"Starting multi-namespace monitor for: {', '.join(self.namespaces)}")
        while True:
            self.check_all_namespaces()
            time.sleep(self.check_interval)


if __name__ == "__main__":
    monitor = MultiNamespacePodMonitor()
    monitor.start_monitoring()